/**
  ************************************* Copyright ******************************
  * FileName   : ads1115.c
  * Version    : v1.0
  * Author     : yychao
  * Date       : 2023-12-15
  * Description:
  * Function List:
  	1. ....
  	   <version>:
  <modify staff>:
  		  <data>:
   <description>:
  	2. ...
  ******************************************************************************
 */
#include "iic2.h"
#include "ads1115.h"
#include "log.h"
//ADS1115具有四个寄存器
//1.地址指针寄存器（只写）
//2.转换寄存器(P[1:0] = 0x00) [reset = 0x0000]	（只读）
//3.配置寄存器(P[1:0] = 0x01) [reset = 0x8583]	（只写）
//4.比较器使用的上下阈值以二进制补码格式存储在两个16位寄存器。
//	Lo_thresh (P[1:0] = 2H) [reset = 8000h]
//	Hi_thresh (P[1:0] = 3H) [reset = 7FFFh]寄存器
//写时序操作步骤：
//   1.发送写地址给ADS1115(0x90);
//   2.向地址指针寄存器写数据，后两位有效，只能写0x00,0x01,0x02,0x03;
//   3.发送数据给ADS1115（高位在前）


//读时序操作步骤：
//   1.发送写地址给ADS1115(0x90);
//   2.向地址指针寄存器写数据，后两位有效，只能写0x00,0x01,0x02,0x03;
//#define  DATA_REG  0x00			//转换数据寄存器
//#define  CONF_REG  0x01			//控制字设置寄存器
//#define  LOTH_REG  0x02			//最低阀值寄存器
//#define  HITH_REG  0x03			//最高阀值寄存器
//   3.发送读地址给ADS1115(0x91);
//   4.读取ADS1115的数据（两个字节，MSB先行）;


// ADS1115以二进制补码格式提供16位数据
// 正满量程（+FS）输入时，输出的AD值代码为7FFFh
// 负满量程（-FS）输入时，输出的AD值代码为8000h



void ADS1115_Init(void)
{
    IIC2_Init();
}
void ADS1115_Config(uint8_t configH,uint8_t configL)
{
    IIC2_Start();           						//发送起始位
    IIC2_SendByte(ADS1115_WRITE_ADDRESS);      		//发送器件地址（写），厂家提供
    IIC2_wait_ACK();           						//等待应答
    IIC2_SendByte(ADS1015_REG_POINTER_CONFIG);		//写指针寄存器，指向配置寄存器
    IIC2_wait_ACK();           						//等待应答
    IIC2_SendByte(configH);      					//写配置字高字节
    IIC2_wait_ACK();           						//等待应答
    IIC2_SendByte(configL);      					//写配置字低字节
    IIC2_wait_ACK();          						//等待应答
    IIC2_Stop();            						//发送停止位
}
void ADS1115_SingleRead(uint8_t configH,uint8_t configL)
{
    uint32_t ADCdata = 0;
    double val = 0;
    uint32_t adcdath = 0, adcdatl = 0;
    uint32_t range = 0;

    IIC2_Start();
    IIC2_SendByte(ADS1115_WRITE_ADDRESS);              		//发送器件地址（写）
    IIC2_wait_ACK();                   						//等待应答
    IIC2_SendByte(ADS1015_REG_POINTER_CONVERT);				//写配置寄存器指针，指向转换寄存器
    IIC2_wait_ACK();                   						//等待应答
    IIC2_Stop();											//发送停止位
    IIC2_Start();                   						//再次发送起始位
    IIC2_SendByte(ADS1115_READ_ADDRESS);              		//发送器件地址（读）
    IIC2_wait_ACK();										//等待应答
    adcdath = IIC2_RcvByte();        						//读转换结果高字节
    IIC2_ACK();												//发送应答
    adcdatl = IIC2_RcvByte();        						//读转换结果低字节
    IIC2_NACK();                       						//接收器是主控器，在收到最后一个字节后，发送一个NACK信号
    IIC2_Stop();											//发送停止位
    ADCdata=adcdath*256+adcdatl;  							//将16位转换结果存在ADCdata寄存器中

//	LOG_ERROR("-- ADC %X H %x L %x \r\n",ADCdata, adcdath, adcdatl);

    range  = (0x0E & configH)>>1;
//	LOG_ERROR("range %d \r\n", range);

    switch(range)//量程对应的分辨率
    {
    case(0x00):
        LOG_INFO("range-val 6.144 \r\n");
        val=(double)ADCdata*187.5/1000000.0;//
        break;
    case(0x01):
        LOG_INFO("range-val 4.096 \r\n");
        if(ADCdata < 0x8000) {
            val=(double)ADCdata*125/1000000.0;
        } else {
            val=(double)(0xffff - ADCdata)*125/1000000.0;
        }

        break;
    case(0x02):
//        LOG_INFO("range-val 2.048 \r\n");
        if(ADCdata < 0x8000) {
            val=(double)ADCdata*62.5/1000000.0;
        } else {
            val=(double)(0xffff - ADCdata)*62.5/1000000.0;
        }
        break;
    case(0x03):
        LOG_INFO("range-val 1.024 \r\n");
        val=(double)ADCdata*31.25/1000000.0;
        break;
    case(0x04):
        LOG_INFO("range-val 0.512 \r\n");
        val=(double)ADCdata*15.625/1000000.0;
        break;
    case(0x05):
        LOG_INFO("range-val 0.256 \r\n");
        val=(double)ADCdata*7.8125/1000000.0;
        break;
    }

//    LOG_IMPORT("val %f \r\n", val);


}

void ADS1115_CmpRead(uint8_t configH,uint8_t configL, double* data)
{
    uint32_t ADCdata = 0;
    double val = 0;
    uint32_t adcdath = 0, adcdatl = 0;
    uint32_t range = 0;

    IIC2_Start();
    IIC2_SendByte(ADS1115_WRITE_ADDRESS);              		//发送器件地址（写）
    IIC2_wait_ACK();                   						//等待应答
    IIC2_SendByte(ADS1015_REG_POINTER_CONVERT);				//写配置寄存器指针，指向转换寄存器
    IIC2_wait_ACK();                   						//等待应答
    IIC2_Stop();
    IIC2_Start();                   						//再次发送起始位
    IIC2_SendByte(ADS1115_READ_ADDRESS);              		//发送器件地址（读）
    IIC2_wait_ACK();
    adcdath = IIC2_RcvByte();        						//读转换结果高字节
    IIC2_ACK();
    adcdatl = IIC2_RcvByte();        						//读转换结果低字节

    IIC2_NACK();                       						//接收器是主控器，在收到最后一个字节后，发送一个NACK信号
    IIC2_Stop();
    ADCdata=adcdath*256+adcdatl;  							//将16位转换结果存在ADCdata寄存器中

//	LOG_ERROR("-- ADC %X H %x L %x \r\n",ADCdata, adcdath, adcdatl);

    range  = (0x0E & configH)>>1;
//	LOG_ERROR("range %d \r\n", range);


    switch(range)//量程对应的分辨率
    {
    case(0x00):
        LOG_INFO("range-val 6.144 \r\n");
        val=(double)ADCdata*187.5/1000000.0;//
        break;
    case(0x01):
        LOG_INFO("range-val 4.096 \r\n");
        if(ADCdata < 0x8000) {
            val=(double)ADCdata*125/1000000.0;
        } else {
            val=(double)(0xffff - ADCdata)*125/1000000.0;
        }
        break;
    case(0x02):
//        LOG_INFO("range-val 2.048 \r\n");
        if(ADCdata < 0x8000) {
            val=(double)ADCdata*62.5/1000000.0;
        } else {
            val=(double)(0xffff - ADCdata)*62.5/1000000.0;
        }
        break;
    case(0x03):
        LOG_INFO("range-val 1.024 \r\n");
        val=(double)ADCdata*31.25/1000000.0;
        break;
    case(0x04):
        LOG_INFO("range-val 0.512 \r\n");
        val=(double)ADCdata*15.625/1000000.0;
        break;
    case(0x05):
        LOG_INFO("range-val 0.256 \r\n");
        val=(double)ADCdata*7.8125/1000000.0;
        break;
    }

    *data =  val;
//    LOG_IMPORT("val %f \r\n", val);


}



void GildeAverageValueFilter(double* array, double* new_val, uint8_t len)
{
    double max = 0;
    double min = 0;
    double cache = 0;
    max = array[0];
    for(uint8_t i = 0; i < len ; i++) {
        if(max < array[i]) {
            max = array[i];
        } else {
        }
    }
    LOG_INFO("max %f \r\n", max);

    min = array[0];
    for(uint8_t i = 0; i < len ; i++) {
        if(min > array[i]) {
            min = array[i];
        } else {
        }
    }
    LOG_INFO("min %f \r\n", min);


    for(uint8_t i = 0; i < len; i++) {
        cache += array[i];

    }

    cache = cache- max- min;
    cache = cache / (len -2);
    LOG_INFO("avg %f \r\n", cache);
    *new_val = cache;
//	LOG_INFO("new_val %f \r\n", *new_val);

}


#if 0
LOG_INFO("A0_CONFIG_REG %x %x\r\n",A0_CONFIG_REG_H, A0_CONFIG_REG_L);
ADS1115_Init();
SysTick_Delay_Ms(30);
ADS1115_Config(A0_CONFIG_REG_H, A0_CONFIG_REG_L);
SysTick_Delay_Ms(30);
ADS1115_SingleRead(A0_CONFIG_REG_H, A0_CONFIG_REG_L);


LOG_INFO("A1_CONFIG_REG %x %x\r\n",A1_CONFIG_REG_H, A1_CONFIG_REG_L);
ADS1115_Init();
SysTick_Delay_Ms(30);
ADS1115_Config(A1_CONFIG_REG_H, A1_CONFIG_REG_L);
SysTick_Delay_Ms(30);
ADS1115_SingleRead(A1_CONFIG_REG_H, A1_CONFIG_REG_L);

LOG_INFO("A2_CONFIG_REG %x %x\r\n",A2_CONFIG_REG_H, A2_CONFIG_REG_L);
ADS1115_Init();
SysTick_Delay_Ms(30);
ADS1115_Config(A2_CONFIG_REG_H, A2_CONFIG_REG_L);
SysTick_Delay_Ms(30);
ADS1115_SingleRead(A2_CONFIG_REG_H, A2_CONFIG_REG_L);

LOG_INFO("A3_CONFIG_REG %x %x\r\n",A3_CONFIG_REG_H, A3_CONFIG_REG_L);
ADS1115_Init();
SysTick_Delay_Ms(30);
ADS1115_Config(A3_CONFIG_REG_H, A3_CONFIG_REG_L);
SysTick_Delay_Ms(30);
ADS1115_SingleRead(A3_CONFIG_REG_H, A3_CONFIG_REG_L);
#endif
